<?php


use app\model\RegionDao;
use think\admin\extend\JwtExtend;
use think\admin\model\SystemConfig;
use think\exception\HttpResponseException;


function sub_str(string $str, int $length, string $suffix = '...'): string
{
    $len = mb_strlen($str, 'utf-8');
    if ($len <= $length) {
        return $str;
    }
    return mb_substr($str, 0, $length, 'UTF-8') . $suffix;
}

function show_error($info, $data = '{-null-}', $code = 0): void
{
    if ($data === '{-null-}') $data = new stdClass();
    $result = ['code' => $code, 'info' => is_string($info) ? lang($info) : $info, 'data' => $data];
    if (JwtExtend::isRejwt()) $result['token'] = JwtExtend::token();
    throw new HttpResponseException(json($result));
}


//生成token
function createToken($userid)
{
    $time = time();
    $end_time = time() + 86400;
    $info = $userid . '.' . $time . '.' . $end_time; //设置token过期时间为一天
    //根据以上信息信息生成签名（密钥为 SIGNATURE 自定义全局常量)
    $key = env('KEY', 'change_me');
    $signature = hash_hmac('md5', $info, $key);
    //最后将这两部分拼接起来，得到最终的Token字符串
    return $token = base64_encode($info) . '.' . $signature;
}

//检查token
function checkToken($token)
{
    if (!isset($token) || empty($token)) {
        $data['code'] = '400';
        $data['message'] = '非法请求';
        return $data;
    }
    //对比token
    $explode = explode('.', $token); //以.分割token为数组
    if (count($explode) < 2) {
        $data['code'] = '400';
        $data['message'] = '非法访问~';
        return $data;
    }
    $signature = $explode[1];
    $info = base64_decode($explode[0]);
    $explode = explode('.', $info);
    if (count($explode) < 3) {
        $data['code'] = '400';
        $data['message'] = '非法访问';
        return $data;
    }
    //if (time() > $explode[2]) {
    //    $data['code'] = '401';
    //    $data['message'] = 'Token已过期,请重新登录';
    //    return $data;
    //}
    $uid = $explode[0];
    $info = $explode[0] . '.' . $explode[1] . '.' . $explode[2]; //信息部分

    $key = env('KEY', 'change_me');

    $true_signature = hash_hmac('md5', $info, $key); //正确的签名
    if ($true_signature != $signature) {
        $data['code'] = '400';
        $data['message'] = '非法访问!!';
        return $data;
    }
    $data['code'] = '200';
    $data['message'] = 'SUCCESS';
    $data['uid'] = intval($uid);
    return $data;
}

function jumpUrl($code, $message, $url)
{
    throw new HttpResponseException(json(['code' => $code, 'info' => $message, 'url' => $url]));
}

function getAreaName($code): array
{
    $arr = [];
    $info = RegionDao::where('code', $code)->find();
    if (empty($info)) {
        return [];
    }
    array_unshift($arr, $info->name);
    if (!empty($info->parent_code)) {
        $ret = getAreaName($info->parent_code);
        $arr = array_merge($ret, $arr);
    }
    return $arr;
}

function getArea($code): array
{
    $arr = [];
    $info = RegionDao::where('code', $code)->find();
    if (empty($info)) {
        return [];
    }
    array_unshift($arr, $info);
    if (!empty($info->parent_code)) {
        $ret = getAreaName($info->parent_code);
        $arr = array_merge($ret, $arr);
    }
    return $arr;
}


function getTree($result = [], $pid = 0)
{
    $tree = [];
    if (is_array($result)) {
        foreach ($result as $v) {
            if ($v['pid'] == $pid) {
                $children = getTree($result, $v['id']);
                if ($children) {
                    $v['children'] = $children;
                }
                $tree[] = $v;
            }
        }
    }
    return $tree;
}

function curl_get($url, $data = [],$header=[])
{
    $curl = curl_init();
    if (!empty($data)) {
        if (is_array($data)) {
            $query = http_build_query($data);
            $url .= '?' . $query;
        }
    }
    if (!empty($header)) {
        curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
    }
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_HEADER, 0);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
    $info = curl_exec($curl);
    curl_close($curl);
    return $info;
}

function curl_post($url, $data, $header = [], $isJson = 0)
{
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_HEADER, 0);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($curl, CURLOPT_POST, 1);
    if (is_string($data)) {
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
    } elseif (is_array($data)) {
        $postData = '';
        if ($isJson == 1) {
            $postData = json_encode($data, JSON_UNESCAPED_UNICODE);
            $header[] = 'Content-type:application/json;charset=UTF-8';
        } else {
            $postData = http_build_query($data);
            $header[] = 'Content-Type:application/x-www-form-urlencoded; charset=UTF-8';
        }
        curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
    }
    if (!empty($header)) {
        curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
    }
    $info = curl_exec($curl);
    curl_close($curl);
    return $info;
}

//queue('虚拟发货','virtual:delivery',30,['order_id'=>100])
function queue(string $title, string $command, int $later = 0, array $data = [], int $rscript = 1, int $loops = 0): string
{
    if (!empty($data)) {
        foreach ($data as $k => $v) {
            if (is_string($k)) {
                $command.= " --{$k} {$v}";
            }else{
                $command.= " {$v}";
            }
        }
    }
    return sysqueue($title, $command, $later, $data, $rscript, $loops);
}
// 分布式锁
function acquireLock($lockKey,$expire=10) {
    $redis=cache()->store('redis')->handler();
    $prefix=config('cache.stores.redis.prefix','');
    $lockKey = $prefix.$lockKey;
    // 尝试加锁，设置过期时间10秒
    return $redis->set($lockKey, 1, ['nx', 'ex' => $expire]); // 返回true或false表示是否成功获取锁
}
// 释放锁
function releaseLock($lockKey) {
    $redis=cache()->store('redis')->handler();
    $prefix=config('cache.stores.redis.prefix','');
    $lockKey = $prefix.$lockKey;
    $redis->del($lockKey); 
}

function duration($time = 0)
{
    if ($time <= 0) {
        return '';
    }
    $days = floor($time / 86400);
    $times = $time - 86400 * $days;
    $hours = floor($times / 3600);
    $times = $times - 3600 * $hours;
    $minutes = floor($times / 60);
    $seconds = $times - 60 * $minutes;
    $str = '';
    if ($days > 0) {
        $str .= $days . '天';
    }
    if ($hours > 0) {
        $str .= $hours . '小时';
    }
    if ($minutes > 0) {
        $str .= $minutes . '分';
    }
    if ($seconds > 0) {
        $str .= $seconds . '秒';
    }
    return $str;
}
function isJson($string = '', $assoc = true)
{
    if (is_string($string)) {
        $data = json_decode($string, $assoc);
        if (($data && is_object($data)) || (is_array($data) && !empty($data))) {
            return true;
        }
    }
    return false;
}
function getOrderNo($uid)
{
    return date('Ymd') . $uid . str_pad(rand(1000, 9999), 4, "0", STR_PAD_LEFT);
}



/**
 * 格式化金额，去除不必要的 .00
 * @param string|float|null $money 金额
 * @return float|int 格式化后的金额
 */
function formatMoney(string|float|null $money)
{
    if (is_null($money)) {
        return 0;
    }
    if (floor($money) == $money) {
        return (int)$money;
    }
    return (float)sprintf('%.2f', $money);
}


function delivery($name = null)
{
    $list = [
        ['name' => '中通快递', 'code' => 'ZTO'],
        ['name' => '圆通快递', 'code' => 'YTO'],
        ['name' => '申通快递', 'code' => 'STO'],
        ['name' => '顺丰快递', 'code' => 'SF'],
        ['name' => '韵达快递', 'code' => 'YUNDA'],
        ['name' => '跨越速运', 'code' => 'KYE'],
        ['name' => '极兔速递', 'code' => 'JTSD'],
        ['name' => '京东', 'code' => 'JD'],
    ];
    return $name ? array_column($list, 'name', 'code')[$name] : $list;
}

